#include "sStretch.h"


namespace sgui
{
namespace res
{ 
    
const f32 sStretch::DEFAULT_DIVIDER = 0.125f;

void sStretch::getDataMatrix(sStretchMatrix& matrix, const math::sRectf& rect, const math::sPointf& texSize) const
{
	const math::sPointf size = rect.getSize();
	const math::sPointf pos = rect.getPosition();

	math::sPointf DIVIDERS[ESD_COUNT] = {
		getDivider(ESD_FIRST),
		getDivider(ESD_SECOND)
	};

	const math::sPointf dividersSize = texSize * (DIVIDERS[ESD_FIRST] + DIVIDERS[ESD_SECOND]);

	if (dividersSize.X >= rect.W)
	{
		const float coef = DIVIDERS[ESD_FIRST].X / (DIVIDERS[ESD_FIRST].X + DIVIDERS[ESD_SECOND].X);

		DIVIDERS[ESD_FIRST].X = (rect.W * coef) / texSize.X;
		DIVIDERS[ESD_SECOND].X = (rect.W * (1 - coef)) / texSize.X;
	}

	if (dividersSize.Y >= rect.H)
	{
		const float coef = DIVIDERS[ESD_FIRST].Y / (DIVIDERS[ESD_FIRST].Y + DIVIDERS[ESD_SECOND].Y);

		DIVIDERS[ESD_FIRST].Y = (rect.H * coef) / texSize.Y;
		DIVIDERS[ESD_SECOND].Y = (rect.H * (1 - coef)) / texSize.Y;
	}

	const math::sPointf pos_coefs[3] = {
		math::sPointf(0, 0),
		texSize * DIVIDERS[ESD_FIRST],
		size - texSize * DIVIDERS[ESD_SECOND]
	};
	const math::sPointf size_coefs[3] = {
		texSize * DIVIDERS[ESD_FIRST],
		size - texSize * (DIVIDERS[ESD_FIRST] + DIVIDERS[ESD_SECOND]),
		texSize * DIVIDERS[ESD_SECOND]
	};

	for (int j = 0; j < 3; ++j)
	{
		for (int i = 0; i < 3; ++i)
		{
			matrix.m_data[j][i] = math::sRectf(
				pos + math::sPointf(pos_coefs[i].X, pos_coefs[j].Y), 
				math::sPointf(size_coefs[i].X, size_coefs[j].Y)
			);
		}
	}
}

void sStretch::getTextureMatrix(sStretchMatrix& matrix, const math::sPointf& texSize) const
{
	const math::sPointf pos_coefs[3] = {
		math::sPointf(0, 0),
		texSize * getDivider(ESD_FIRST),
		texSize * (math::sPointf(1, 1) - getDivider(ESD_SECOND))
	};

	const math::sPointf size_coefs[3] = {
		texSize * getDivider(ESD_FIRST),
		texSize * (math::sPointf(1, 1) - (getDivider(ESD_FIRST) + getDivider(ESD_SECOND))),
		texSize * getDivider(ESD_SECOND)
	};

	for (int j = 0; j < 3; ++j)
	{
		for (int i = 0; i < 3; ++i)
		{
			matrix.m_data[j][i] = 
				math::sRectf(
					pos_coefs[i].X, pos_coefs[j].Y, 
					size_coefs[i].X, size_coefs[j].Y
				);
		}
	}
}

void sStretch::save(db::Record& file) const
{
	file[L"m"].Set((u32)m_mode);
	if (m_mode == ESM_STRETCH)
	{
		db::Record &dividers = file[L"d"];
		dividers.setSize(ESD_COUNT);
		for (u32 i = 0; i < ESD_COUNT; ++i)
		{
			m_dividers[i].save(dividers[i]);
		}
	}
}

void sStretch::load(const db::Record& file)
{
	m_mode = (EStretchMode)file[L"m"].GetAsInt();	

	if (m_mode == ESM_STRETCH)
	{
		const db::Record &dividers = file[L"d"];

		for (u32 i = 0; i < ESD_COUNT; ++i)
		{
			m_dividers[i].load(dividers[i]);
		}
	}
}

void sStretch::clear()
{
    m_dividers[ESD_FIRST].set(DEFAULT_DIVIDER, DEFAULT_DIVIDER);
    m_dividers[ESD_SECOND].set(DEFAULT_DIVIDER, DEFAULT_DIVIDER);
	
	m_mode = ESM_SCALE;
}

#ifdef _EDITOR
void sStretch::exportRTTI(rtti::sInfoList& list)
{

}
#endif

sStretch::sStretch() :
	m_mode(ESM_SCALE)
{
    m_dividers[ESD_FIRST].set(DEFAULT_DIVIDER, DEFAULT_DIVIDER);
    m_dividers[ESD_SECOND].set(DEFAULT_DIVIDER, DEFAULT_DIVIDER);
}

};
};